//
//  APPAssetInfo.swift
//  Exchange
//
//  Created by 孟祥群 on 2018/8/7.
//  Copyright © 2018年 common. All rights reserved.
//

import UIKit
typealias assetBlock = () ->()
class APPAssetInfo: NSObject {
    static let `default` = APPAssetInfo()
    
    typealias CoinAssetBack = ()->()
    typealias LegalAssetBack = ()->()
    
    private var coinDataCallBack: CoinAssetBack?
    private var legalDataCallBack: LegalAssetBack?
    
    var totalCoin:String = "0" //币币资产
    var totalBtc:String = "0"//拥有的BTC数量
    var totalLevCoin = "0" //法币资产
    var totalLevBtc = "0"//法币BTC数量
    var totalVerCoin = "0" //杠杆资产
    var totalVerBtc = "0"//杠杆BTC数量
    
    var needRefreshCoinKind:Bool = false //是否需要刷新币种信息
    
    //币币账户资产
    lazy var coinAssetArr:Array<AssetModel> = {
        let array:Array<AssetModel> = []
        return array
    }()
    //币币账户资产有值数据
    lazy var haveCoinArr:Array<AssetModel>  = {
        let array:Array<AssetModel> = []
        return array
    }()
    //法币账户资产
    lazy var legalAssetArr:Array<AssetModel> = {
        let array:Array<AssetModel> = []
        return array
    }()
    //法币账户有值数据
    lazy var haveLegalArr:Array<AssetModel>  = {
        let array:Array<AssetModel> = []
        return array
    }()
    //杠杆账户资产
    lazy var leverAssetArr:Array<AssetModel> = {
        let array:Array<AssetModel> = []
        return array
    }()
    //杠杆账户有值数据
    lazy var haveLeverArr:Array<AssetModel>  = {
        let array:Array<AssetModel> = []
        return array
    }()
    
   //币币账户支持的币种
    lazy var coninKidArray:Array<TradeCoinModel> = {
        let array:Array<TradeCoinModel> = []
        return array
    }()
    //杠杆账户支持的数据
    lazy var leverKindArray:Array<TradeCoinModel> = {
        let array:Array<TradeCoinModel> = []
        return array
    }()
    
    lazy var request: AssetRequest = {
        let api = AssetRequest()
        api.type = .coinType
        api.dataReformer = self
        api.paramSource = self
        api.delegate = self
        return api
    }()
    
    lazy var legalRequest:AssetRequest = {
        let api = AssetRequest()
        api.type = .legalType
        api.dataReformer = self
        api.paramSource = self
        api.delegate = self
        return api
    }()
    lazy var leverRequest:AssetRequest = {
        let api = AssetRequest()
        api.type = .leverType
        api.dataReformer = self
        api.paramSource = self
        api.delegate = self
        return api
    }()
    
    
    
    /// 获取不同币种对应的信息
    ///
    /// - Parameter coinName: 币种名称 默认BTC CNY
  func archiveCoinInformation(semaphore:DispatchSemaphore? = nil,block:securityBlock? = nil)  {
        AppContext.default.getCoinKind(isRefresh:true, callBack: { (array) in
            self.coninKidArray = array
            if semaphore != nil {
                semaphore?.signal()
            }
        })
    }
    
  func archiveLeverCoInformation(semaphore:DispatchSemaphore? = nil) {
        AppContext.default.getTradeCoins(isRefresh:true, callBack: { (array) in
            self.leverKindArray = array
            if semaphore != nil {
                semaphore?.signal()
            }
        })
    }
    
   public func archiveAll(_ view:UIView?,block:assetBlock? = nil) {
        self.needRefreshCoinKind = false
        CYMBShow.openIndicator(message: nil, view: view)
        let group  = DispatchGroup()
        let quene = DispatchQueue(label: "queuename", attributes: .concurrent)
        quene.async(group: group, qos: .default, flags: []) {
            let semaphore =  DispatchSemaphore(value: 0)
            self.archiveInformation(semaphore: semaphore)
            semaphore.wait()
        }
        quene.async(group: group, qos: .default, flags: []) {
            let semaphore =  DispatchSemaphore(value: 0)
            self.archivelegalInformation(semaphore: semaphore)
            semaphore.wait()
        }
        //目前版本不支持杠杆 先注销
        //        quene.async(group: group, qos: .default, flags: []) {
        //            let semaphore =  DispatchSemaphore(value: 0)
        //            self.archiveLeverInformation(semaphore: semaphore)
        //            semaphore.wait()
        //        }
        
        quene.async(group: group, qos: .default, flags: []) {
            let semaphore =  DispatchSemaphore(value: 0)
            self.archiveCoinInformation(semaphore: semaphore)
            semaphore.wait()
        }
        quene.async(group: group, qos: .default, flags: []) {
            let semaphore =  DispatchSemaphore(value: 0)
            self.archiveLeverCoInformation(semaphore: semaphore)
            semaphore.wait()
        }
        group.notify(queue: DispatchQueue.main) {
            self.mergingData(dataArr: self.coinAssetArr,type: .coinType)
            self.mergingData(dataArr: self.legalAssetArr,type: .legalType)
            self.mergingData(dataArr: self.leverAssetArr,type: .leverType)
            if block != nil {
               block!()
            }
            CYMBShow.colseIndicator(view: view)
        }
    }
    
   private func mergingData(dataArr:[AssetModel],type:CoinAccountType) {
        var supportArr:[TradeCoinModel] = []
        if type == .legalType {
            supportArr = leverKindArray
        }else {
            supportArr = coninKidArray
        }
        var newDataArr:[AssetModel] =  []
        
        (supportArr as NSArray).enumerateObjects { (source, index, stop) in
            let model = (source as? TradeCoinModel)
            var exchangeModel:AssetModel = AssetModel()
            var isExist = false
            (dataArr as NSArray).enumerateObjects({ (data, position, end) in
                let smallModel = (data as? AssetModel)
                if model?.coinCode == smallModel?.coinCode {
                    exchangeModel = smallModel!
                    exchangeModel.coinPrecision = model?.coinPrecision ?? 8
                    isExist = true
                    end.initialize(to: true)
                }
            })
            if !isExist {
                let info = AssetModel()
                info.logoUrl = model?.logoUrl ?? ""
                info.coinCode = model?.coinCode ?? ""
                info.coinPrecision = model?.coinPrecision ?? 8
                newDataArr.append(info)
            }else {
                newDataArr.append(exchangeModel)
            }
            
        }
        if type == .coinType {
            self.coinAssetArr = newDataArr
        }else if type == .legalType {
            self.legalAssetArr = newDataArr
        }else {
            self.leverAssetArr = newDataArr
        }
       self.archiveHaveAssetArr(dataArr: newDataArr, type: type)
    }
    
    func archiveHaveAssetArr(dataArr:[AssetModel],type:CoinAccountType) {
        for model in dataArr {
            if model.enableAmount != 0 {
                if type == .coinType {
                    self.totalCoin  =  self.archiveAllMoney(model: model, totolMoeny: (self.totalCoin))
                    self.totalBtc = self.archiveAllBtc(model: model,totolMoeny: (self.totalBtc))
                    self.haveCoinArr.append(model)
                }else if type == .legalType {
                    self.totalLevCoin  =  self.archiveAllMoney(model: model, totolMoeny: (self.totalLevCoin))
                    self.totalLevBtc = self.archiveAllBtc(model: model,totolMoeny: (self.totalLevBtc))
                    self.haveLegalArr.append(model)
                }else {
                    self.totalVerCoin  =  self.archiveAllMoney(model: model, totolMoeny: (self.totalVerCoin))
                    self.totalVerBtc = self.archiveAllBtc(model: model,totolMoeny: (self.totalVerBtc))
                    self.haveLeverArr.append(model)
                }
            }
        }
    }
    
    
    /// 获取法币资产
    ///
    /// - Parameter semaphore: 信号源
   private func archivelegalInformation(semaphore:DispatchSemaphore) {
        self.legalRequest.loadData()
        self.legalDataCallBack = {() in
            semaphore.signal()
        }
       
    }
    
    
    /// 获取币币资产
    ///
    /// - Parameter semaphore: 信号源
    private func archiveInformation(semaphore:DispatchSemaphore)  {
        self.request.loadData()
        self.coinDataCallBack = {() in
            semaphore.signal()
        }
        
    }
    
  private  func changeLegalAsset(result:[String : Any]?) {
        self.haveLegalArr.removeAll()
        self.legalAssetArr.removeAll()
        self.totalLevCoin = "0"
        self.totalLevBtc = "0"
        let dic:[String:Any]? = result != nil ? result : nil
        if dic == nil {
            return
        }
        if dic?["data"] as? Array<[String : Any]> == nil  {
            return
        }
        
        let array:Array<[String : Any]> = dic?["data"] as! Array<[String : Any]>
        for dic in array {
            let model = AssetModel(JSON: dic)
            if model != nil {
                self.legalAssetArr.append(model!)
            }
        }
        
    }
    
    
  private func changeCoinAsset(result:[String : Any]?)  {
        self.haveCoinArr.removeAll()
        self.coinAssetArr.removeAll()
        self.totalCoin = "0"
        self.totalBtc = "0"
        let dic:[String:Any]? = result != nil ? result : nil
        if dic == nil {
            return
        }
        if dic?["data"] as? Array<[String : Any]> == nil  {
            return
        }
        
        let array:Array<[String : Any]> = dic?["data"] as! Array<[String : Any]>
        for dic in array {
            let model = AssetModel(JSON: dic)
            if model != nil {
                self.coinAssetArr.append(model!)
                
            }
        }
    }
    
    
    /// 获取杠杆资产
    ///
    /// - Parameter semaphore: 信号源
//    func archiveLeverInformation(semaphore:DispatchSemaphore)  {
//        self.leverRequest.loadData()
//        self.request(request: leverRequest, success: {[weak self](result) in
//            semaphore.signal()
//            self?.haveleverArr.removeAll()
//            self?.leverArr.removeAll()
//            self?.totalVerCoin = "0"
//            self?.totalVerBtc = "0"
//            let dic:[String:Any]? = result != nil ? result : nil
//            if dic == nil {
//                return
//            }
//            if dic?["data"] as? Array<[String : Any]> == nil  {
//                return
//            }
//
//            let array:Array<[String : Any]> = dic?["data"] as! Array<[String : Any]>
//            for dic in array {
//                let model = AssetModel(JSON: dic)
//                if model != nil {
//                    self?.leverArr.append(model!)
//                }
//            }
//        }) { (response) in
//            semaphore.signal()
//        }
//    }
    
    
   public func updateAsset() {
        self.totalLevCoin = "0"
        self.totalLevBtc = "0"
        for model in self.legalAssetArr {
            self.totalLevCoin  =  self.archiveAllMoney(model: model, totolMoeny: self.totalLevCoin)
            self.totalLevBtc = self.archiveAllBtc(model: model,totolMoeny: self.totalLevBtc)
        }
        self.totalCoin = "0"
        self.totalBtc = "0"
        for model in self.coinAssetArr {
            self.totalCoin  =  self.archiveAllMoney(model: model, totolMoeny: self.totalCoin)
            self.totalBtc = self.archiveAllBtc(model: model,totolMoeny: self.totalBtc)
        }
        self.totalVerCoin = "0"
        self.totalVerBtc = "0"
        for model in self.leverAssetArr {
            self.totalVerCoin  =  self.archiveAllMoney(model: model, totolMoeny: self.totalVerCoin)
            self.totalVerBtc = self.archiveAllBtc(model: model,totolMoeny: self.totalVerBtc)
        }
    }
    
    /// 计算全部资产
    ///
    ///totolMoeny 全部资金
    /// - Parameter model: 资产
    private func archiveAllMoney(model:AssetModel,totolMoeny:String) -> String{
        let totalCoin = totolMoeny
        let money =  AppContext.default.archiveLegalPrice(coinKind: AppCacheInfo.default.currency, legalKind: model.coinCode.count != 0 ? (model.coinCode) : "")
        let currentMoney = CYCalculate.cy_multiplying(firstNumber: money, lastNumber: (model.enableAmount), digit: 2)
        return CYCalculate.cy_add(firstNumber: totalCoin, lastNumber: currentMoney, digit: 2)
    }
    
    private func archiveAllBtc(model:AssetModel,totolMoeny:String) -> String {
        let totalCoin = totolMoeny
        if model.coinCode == "BTC" {
            return CYCalculate.cy_add(firstNumber: totalCoin, lastNumber: model.enableAmount, digit: 8)
        }else {
            let btcKind = AppContext.default.archiveLegalPrice(coinKind: AppCacheInfo.default.currency, legalKind: "BTC")
            let money = AppContext.default.archiveLegalPrice(coinKind: AppCacheInfo.default.currency, legalKind: model.coinCode.count != 0 ? (model.coinCode) : "")
            let currentMoney = CYCalculate.cy_multiplying(firstNumber: money, lastNumber: (model.enableAmount), digit: 8)
            let btcMoney = CYCalculate.cy_dividing(firstNumber: currentMoney, lastNumber: btcKind, digit: 8)
            return CYCalculate.cy_add(firstNumber: totalCoin, lastNumber: btcMoney, digit: 8)
        }
    }
    
    
    /// 检查法币账户是否可划转
    ///
    /// - Returns:
    func chekSupport() -> Bool{
        if legalAssetArr.count == 0 {
            return false
        }
        let model = legalAssetArr.first
        for data in self.coinAssetArr {
            if model?.coinCode == data.coinCode {
                return true
            }
        }
        return false
    }
     
    
}
extension APPAssetInfo: RequestCallBack,RequestDataReformer,RequestParamSource {
    func reform(_ request: BaseRequest, _ data: [String : Any]?) {
        if let _ = request as? AssetRequest {
            let newRequest = request as! AssetRequest
            if newRequest.path() == legalRequest.path() {
                self.changeLegalAsset(result: data)
                if legalDataCallBack != nil {
                    legalDataCallBack!()
                }
            }else if newRequest.path() == self.request.path() {
                self.changeCoinAsset(result: data)
                if coinDataCallBack != nil {
                    coinDataCallBack!()
                }
            }
            
        }
        
    }
    
    func requestDidSucess(_ request: BaseRequest) {
        
    }
    
    func requestDidFail(_ request: BaseRequest) {
        if let _ = request as? AssetRequest {
            let newRequest = request as! AssetRequest
            if newRequest.path() == legalRequest.path() {
                if legalDataCallBack != nil {
                    legalDataCallBack!()
                }
            }else if newRequest.path() == self.request.path() {
                if coinDataCallBack != nil {
                    coinDataCallBack!()
                }
            }
            
        }
    }
    
    func requestParams(_ request: BaseRequest) -> [String : Any]? {
        let pramas: [String:Any] = [:]
        
        return pramas
    }
    
    
}
